package utils

import (
	"fmt"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"runtime"
	"sync"
)

var (
	logger  *zap.Logger
	logOnce sync.Once
)

func GetLogger(srvName string) *zap.Logger {
	logOnce.Do(func() {
		var err error
		encoderConfig := zapcore.EncoderConfig{
			TimeKey:        "time",
			LevelKey:       "level",
			NameKey:        "logger",
			MessageKey:     "path",
			LineEnding:     zapcore.DefaultLineEnding,
			EncodeLevel:    zapcore.LowercaseLevelEncoder, // 小写编码器
			EncodeTime:     zapcore.ISO8601TimeEncoder,    // ISO8601 UTC 时间格式
			EncodeDuration: zapcore.SecondsDurationEncoder,
			EncodeCaller:   zapcore.FullCallerEncoder, // 全路径编码器
		}

		atom := zap.NewAtomicLevelAt(zap.InfoLevel)
		cfg := zap.Config{
			Level:         atom,                                   // 日志级别
			Development:   false,                                  // 开发模式，堆栈跟踪
			Encoding:      "json",                                 // 输出格式 console 或 json
			EncoderConfig: encoderConfig,                          // 编码器配置
			InitialFields: map[string]interface{}{"app": srvName}, // 初始化字段，如：添加一个服务器名称
			//OutputPaths:      []string{"stdout", "logs/api.log"},                  // 输出到指定文件 stdout（标准输出，正常颜色） stderr（错误输出，红色）
			OutputPaths:      []string{"stdout"}, // 输出到指定文件 stdout（标准输出，正常颜色） stderr（错误输出，红色）
			ErrorOutputPaths: []string{"stderr"},
		}

		logger, err = cfg.Build()
		if err != nil {
			panic(fmt.Sprintf("log init fail err: %v", err))
		}
	})
	return logger
}

func LogInfo(msg ...interface{}) {
	pc, _, line, _ := runtime.Caller(1)
	GetLogger("[INFO]").Info(
		fmt.Sprintf("%+v:%v行", runtime.FuncForPC(pc).Name(), line),
		zap.String("日志：", fmt.Sprintf("%+v", msg)),
	)
}

func LogErr(e error, msg ...interface{}) {
	pc, _, line, _ := runtime.Caller(1)
	GetLogger("[ERR]").Error(
		fmt.Sprintf("%+v:%v行", runtime.FuncForPC(pc).Name(), line),
		zap.String("信息：", fmt.Sprintf("%+v", msg)),
		zap.String("错误：", e.Error()),
	)
}
